﻿using System;
using System.Windows;
using System.Reflection;
using System.Windows.Controls;

namespace iTunesPwned.Core.Plugin
{
    public delegate void UpdateSettingsDelegate(object sender);
    public delegate void RegisterTabItemDelegate(object sender, TabItem item);
    public delegate void RegisterMenuItemDelegate(object sender, string name, RoutedEventHandler handler);

    public abstract class PluginBase : IPlugin
    {
        public event RegisterTabItemDelegate RegisterTabItemHandler;
        public event RegisterMenuItemDelegate RegisterMenuItemHandler;

        public Guid Identifier
        {
            get;
            private set;
        }

        public string Name
        {
            get;
            private set;
        }

        public PluginBase(Guid identifier, string name)
        {
            this.Identifier = identifier;

            this.Name = name;
        }

        public abstract void Init();

        protected void RegisterTabItem(TabItem item)
        {
            this.RegisterTabItemHandler(this, item);
        }

        protected void RegisterMenuItem(string name, RoutedEventHandler handler)
        {
            this.RegisterMenuItemHandler(this, name, handler);
        }
    }

    public interface IPlugin
    {
        event RegisterTabItemDelegate RegisterTabItemHandler;
        event RegisterMenuItemDelegate RegisterMenuItemHandler;

        Guid Identifier { get; }

        string Name { get; }

        void Init();
    }

    public interface ISettings
    {
        event UpdateSettingsDelegate UpdateSettings;

        string Serialize();
        void Deserialize(string settings);
    }

    public class PluginCreator
    {
        public static IPlugin CreateInstance(string assemblyFile)
        {
            Assembly assembly;
            IPlugin pluginInstance = null;

            assembly = Assembly.LoadFrom(assemblyFile);

            foreach (Type pluginType in assembly.GetTypes())
            {
                if (typeof(IPlugin).IsAssignableFrom(pluginType) && (pluginType != typeof(IPlugin) && pluginType != typeof(PluginBase)))
                {
                    pluginInstance = (IPlugin)Activator.CreateInstance(pluginType);

                    break;
                }
            }

            return pluginInstance;
        }
    }
}
